#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>

template<typename T>
class LockQueue
{
public:
    LockQueue() = default;
    ~LockQueue() = default;
    
    // 禁用拷贝构造和赋值
    LockQueue(const LockQueue&) = delete;
    LockQueue& operator=(const LockQueue&) = delete;
    
    // 向队列中添加元素
    void Push(const T& item)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_queue.push(item);
        m_condition.notify_one();
    }
    
    void Push(T&& item)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_queue.push(std::move(item));
        m_condition.notify_one();
    }
    
    // 从队列中弹出元素（阻塞版本）
    T Pop()
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        while (m_queue.empty()) {
            m_condition.wait(lock);
        }
        T result = std::move(m_queue.front());
        m_queue.pop();
        return result;
    }
    
    // 尝试弹出元素（非阻塞版本）
    bool TryPop(T& item)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (m_queue.empty()) {
            return false;
        }
        item = std::move(m_queue.front());
        m_queue.pop();
        return true;
    }
    
    // 带超时的弹出元素
    bool PopWithTimeout(T& item, int timeoutMs)
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        auto timeout = std::chrono::milliseconds(timeoutMs);
        
        if (m_condition.wait_for(lock, timeout, [this] { return !m_queue.empty(); })) {
            item = std::move(m_queue.front());
            m_queue.pop();
            return true;
        }
        return false;
    }
    
    // 检查队列是否为空
    bool Empty() const
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_queue.empty();
    }
    
    // 获取队列大小
    size_t Size() const
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_queue.size();
    }
    
    // 清空队列
    void Clear()
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        std::queue<T> empty;
        m_queue.swap(empty);
    }

private:
    mutable std::mutex m_mutex;
    std::queue<T> m_queue;
    std::condition_variable m_condition;
};